/**
  * Author: Mei
  * Date: 2020-12-25 9:36
  * Description: 异步操作类future
  * future一般作为异步结果的传输通道，可以很方便地获取线程函数的返回值；
  * promise用来包装一个值，将数据和future绑定起来，方便线程赋值；
  * package_task用来包装一个可调用对象，将函数和future绑定起来，以便异步调用
  *
  */
#include "head.h"

using namespace std;

int func() {
    return 10;
}

int func1(int i) {
    return i;
}

int Test_Fun(int iVal) {
    std::cout << "Value is:" << iVal << std::endl;
    return iVal + 232;
}

struct func2 {
    int operator()(int i, int j) {
        return 20+i+j;
    }
};

int main() {
    //promise
    promise<int> pr;
    thread t([](promise<int> &p) {
        p.set_value_at_thread_exit(9); //p中value也可以为function、lambda expression、bind expression、another function object
    }, ref(pr));
    future<int> f = pr.get_future();
    auto res = f.get();
    cout << res << endl;
    t.join();

    //package_task包装一个可调用对象，如function、lambda expression、bind expression、another function object
    //packaged_task<int(int)> task([](int i) { return 7+i; }); //lambda表达式
    //packaged_task<int()> task(func); //普通函数
    //function<int(int)> ff1 = bind(func1, placeholders::_1); //bind表达式

    packaged_task<int(int,int)> task(move(func2())); //函数对象 func2()应该创建一个临时对象 所以要么使用()包起来要么使用move() 应该move更好
    //task(50); //这样调用不是异步执行
    future<int> f1 = task.get_future(); //只写函数返回值
    thread t1(move(task), 30, 9); //这个地方进行传参 执行move(task)之后 task就不能再用了
    cout << f1.get() << endl;
    t1.join();


    return 0;
}